layui.define(['jquery', 'table', 'form'], function (exports) {
    const {jquery: $} = layui;

    exports('binder', {
        //内置规则
        __rules: [
            //layui内置绑定规则
            {type: "form", event: "select", selector: "select[lay-filter]"},
            {
                type: "form",
                event: "checkbox",
                selector: 'input[type="checkbox"][lay-filter]:not([lay-skin="switch"])',
            },
            {
                type: "form",
                event: "switch",
                selector: 'input[type="checkbox"][lay-filter][lay-skin="switch"]',
            },
            {
                type: "form",
                event: "radio",
                selector: 'input[type="radio"][lay-filter]',
            },
            {
                type: "form",
                event: "submit",
                selector: "[lay-submit][lay-filter]",
            },

            //layui内置表格绑定规则
            {
                type: "table",
                event: "toolbar",
                selector: "table[lay-filter]",
            },
            {type: "table", event: "tool", selector: "table[lay-filter]"},
            {type: "table", event: "edit", selector: "table[lay-filter]"},
            {type: "table", event: "row", selector: "table[lay-filter]", method: "tableRow"},

            //自定义绑定规则
            {
                type: "custom",
                event: "click",
                selector: "a[lay-filter]:not([lay-submit])",
                attr: "lay-filter",
            },
            {
                type: "custom",
                event: "click",
                selector: ".layui-btn[lay-filter]:not([lay-submit]):not(a)",
                attr: "lay-filter",
            },
            {
                type: "custom",
                event: "input",
                selector: ".layui-input[lay-input]",
                attr: "lay-input",
            },
            {
                type: "custom",
                event: "change",
                selector: ".layui-input[lay-input]",
                attr: "lay-change",
            },
        ],
        /**
         * 执行绑定逻辑
         * @param target 绑定目标
         * @param rules 自定义绑定规则
         */
        run: function (target, rules = []) {
            //直接合并，出现target指向异常，都只能操作最后一个target，感觉是rule不能直接引用，会导致当前的作用域异常。
            rules = rules.concat(JSON.parse(JSON.stringify(this.__rules)));
            rules.forEach(function (rule) {
                switch (rule.type) {
                    case "table":
                        const tableTarget = $(rule.selector).attr('lay-filter')
                        layui.table.on(rule.event + '(' + tableTarget + ')', function (obj) {
                            const method = rule.method || obj.event;
                            if (target[method]) {
                                target[method](this, obj);
                            }
                        });
                        break;
                    case "form":
                        $(rule.selector).each(function (idx, elem) {
                            //转接一下，防止被修改this
                            var filterValue = $(elem).attr('lay-filter');
                            var filter = (filterValue);
                            if (!filter) {
                                return;
                            }
                            if (target[filter]) {
                                layui.form.on(rule.event + '(' + filterValue + ')', function (data) {
                                    target[filter](data);
                                    return false;
                                });
                            }
                        });
                        break;
                    case "custom":
                        $(rule.selector).unbind(rule.event).bind(rule.event, function () {
                            const method = ($(this).attr(rule.attr));
                            if (target[method]) {
                                target[method](this);
                            }
                        });
                        break;
                }

            });
        },
    });
});
